package org.robot.scm.platform.server.handler;

import static org.robot.scm.platform.server.LockKey.LOCK_KEY;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.stream.Collectors;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.robot.scm.infra.RedisCacheHelper;
import org.robot.scm.pojos.platform.server.ExecuteParam;
import org.robot.scm.utils.JsonHelper;
import org.robot.scm.utils.RandomUtil;

@Slf4j
@NoArgsConstructor
public class ScriptHandler extends BaseHandler implements HttpHandler {

    @Override
    public String getUri() {
        return "/script";
    }

    @Override
    public void handle(HttpExchange exchange) throws IOException {
        log.info("script handler: {} - {}", exchange.getRequestMethod(), exchange.getRequestURI().getPath());
        // 并发校验
        String locker = RedisCacheHelper.get(LOCK_KEY);
        if (StringUtils.isNotBlank(locker)) {
            sendSuccessResponse(exchange, "有任务正在执行中");
            return;
        }

        if (!exchange.getRequestMethod().equalsIgnoreCase("POST")) {
            sendFailureResponse(exchange, "请求非法");
            return;
        }

        String fileKey = RandomUtil.uuidNoLine();
        File targetFile = new File("assets/telegram/" + fileKey + ".sql");

        String requestBody = new BufferedReader(new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n"));
        ExecuteParam executeParam = JsonHelper.toObject(requestBody, ExecuteParam.class);
        executeParam.setFileKey(fileKey);

        if (StringUtils.isBlank(executeParam.getScript())) {
            sendFailureResponse(exchange, "请输入有效的脚本");
            return;
        }

        // 去换行
        StringBuilder command = new StringBuilder();
        String script = executeParam.getScript();
        String[] lines = script.split("\\r?\\n");
        for (String line : lines) {
            handleLine(command, line);
        }
        if (!command.toString().trim().endsWith(";")) {
            command.append(";");
        }
        executeParam.setScript(command.toString().trim());
        if (!isSql(executeParam.getScript())) {
            sendFailureResponse(exchange, "请输入正确的脚本");
            return;
        }
        try (OutputStream out = Files.newOutputStream(targetFile.toPath())) {
            out.write(executeParam.getScript().getBytes(StandardCharsets.UTF_8));
            sendSuccessResponse(exchange, fileKey);
        } catch (IOException e) {
            sendFailureResponse(exchange, e.getMessage());
        }
    }

    public static void handleLine(StringBuilder command, String line) {
        String trimmedLine = line.trim();
        if (lineIsComment(trimmedLine)) {
            command.append(trimmedLine);
            command.append(System.lineSeparator());
        } else if (trimmedLine.contains(";")) {
            command.append(trimmedLine, 0, trimmedLine.lastIndexOf(";"));
            command.append(";").append(System.lineSeparator());
            String substring = StringUtils.substring(trimmedLine, trimmedLine.lastIndexOf(";") + 1, trimmedLine.length());
            if (StringUtils.isNotBlank(substring)) {
                command.append(substring);
            }
            command.append(" ");
        } else if (!trimmedLine.isEmpty()) {
            command.append(trimmedLine).append(" ");
        }
    }

    private static boolean lineIsComment(String trimmedLine) {
        return trimmedLine.startsWith("//") || trimmedLine.startsWith("--") || trimmedLine.startsWith("#");
    }
}
